/*
 * @Author: 姜斌
 * @Date: 2024-05-05 08:59:08
 * @LastEditTime: 2024-05-17 07:10:13
 * @LastEditors: 姜斌
 * @Description: 添加描述信息
 * @FilePath: \be_quna\app.js
 */
const createError = require("http-errors");
const express = require("express");
const path = require("path");
const jwt = require("jsonwebtoken");
// const logger = require("morgan");
const expressJWT = require("express-jwt"); //解析token中间件
const indexRouter = require("./routes/index");
const fileRouter = require("./routes/file");
const usersRouter = require("./routes/users");
const scoreRouter = require("./routes/score");
const imagesRouter = require("./routes/images");
const listsRouter = require("./routes/lists");
const captainRouter = require("./routes/captain");
const app = express();
// config
const config = require("./config");
const timeout = require("connect-timeout");
const cors = require("cors");
const bodyParser = require("body-parser");
const compression = require("compression");
// config.setLogger(process.env.MODE);
// //test data
// global.logger.info({ msg: "info" });
// global.logger.warn({ msg: "warn" });
// global.logger.error({ msg: "error" });
// console.log("global.logger", 888);
//test data
// view engine setup
app.set("views", path.join(__dirname, "views")); // 静态地址
app.set("view engine", "jade"); // 指定静态文件后缀

// app.use(logger("dev"));
app.use(config.setHttpLogger()); //日志
config.setLogger(); // 输出文件
app.use(express.json()); // json格式上传
app.use(express.urlencoded({ extended: false })); // 解析url
app.use(express.static(path.join(__dirname, "public"))); //静态css地址
app.use(express.static(path.join(__dirname, "log_box"))); //日志地址
// app.enable('trust proxy') //允许设置代理
app.use(timeout("80s")); //设置超时时间
app.use(
  cors({
    credentials: true,
    origin: true,
    allowedHeaders: [
      "Content-Type",
      "Authorization', 'Content-Length",
      "X-Requested-With",
    ],
    maxAge: 1728000,
    methods: ["GET", "POST", "OPTIONS", "PUT", "DELETE"],
  })
); //跨域
app.use(compression()); //启动Gzip压缩功能
app.use(bodyParser.json({ limit: "1mb" })); //解析json格式
app.use(bodyParser.urlencoded({ limit: "1mb", extended: false })); //解析form格式
app.use(bodyParser.raw({ limit: "100kb", type: "text/plain" })); //解析二进制格式
app.use(function (req, res, next) {
  // 超时处理
  if (!req.timedout) next();
});
// 一定要在路由之前，封装res.cc函数,统一处理返回信息问题  统一出口

// 注册将JWT字符串解析还原成JSON对象的中间件
// 注意：只要配置成功了express-jwt这个中间件，就可以把解析出来的用户信息，挂载到req.user属性上 使用requestProperty属性进行挂载
// 解析token
app.use(
  expressJWT
    .expressjwt({
      secret: process.env.SECRET_KEY,
      algorithms: ["HS256"],
      requestProperty: "user",
    })
    .unless({ path: ["/lyapi/users/mylogin", "/lyapi/file/uploadfile"] })
);

app.use(async (req, res, next) => {
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith("Bearer")
  ) {
    if (req.url == "/lyapi/users/mylogin" || req.url == "/lyapi/file/uploadfile") {
    } else {
      const token = req.headers.authorization.split(" ")[1];
      const { id } = jwt.verify(token, process.env.SECRET_KEY);
      const resGet = await global.connectRedis.get(id);
      if (resGet !== token) {
        return res.send({
          code: 401,
          msg: "token已失效，请尝试重新登录！",
        });
      }
    }
  }
  res.cc = function (err, code = 1) {
    res.send({
      code,
      msg: err instanceof Error ? err.message : err,
    });
  };
  next();
});

app.use("/lyapi", indexRouter); // 日志
app.use("/lyapi/users", usersRouter); //用户信息
app.use("/lyapi/score", scoreRouter); //分数
app.use("/lyapi/images", imagesRouter); // 图片
app.use("/lyapi/lists", listsRouter); // 各个排行
app.use("/lyapi/captain", captainRouter); //设置队长
app.use("/lyapi/file", fileRouter); // 文件路由

// 401 token时效或者不合法
app.use((err, req, res, next) => {
  //token解析失败导致
  if (err.name === "UnauthorizedError") {
    return res.send({
      code: 401,
      msg: "token已过期，请尝试重新登录！",
    });
  }
  res.send({ code: 500, msg: err.message });
});
// catch 404 and forward to error handler
app.use((req, res, next) => {
  next(createError(404));
});

// error handler 错误日志监听
app.use((err, req, res, next) => {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;
